/* shttpd - circular character buffers
   Copyright (C) 2018 Ariadne Devos

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */

#ifndef _sHT_PAPER_H
#define _sHT_PAPER_H

#include <stdint.h>

/* Text that is passed around and scribbled is called 'paper'. */

/* According to https://stackoverflow.com/questions/42258274/
   should-i-send-data-in-chunks-or-send-it-all-at-once, the exact buffer size
   doesn't really matter. So choose a convenient, round number that allows for
   many concurrent connections. (Increase this value if performance tests tell
   you to do so.)

   This is guaranteed to be a power of 2, and a multiple of 1024. */
#define sHT_PAPER_SIZE 4096
#define sHT_PAPER_SIZE_MAX 4095

/** A single unsigned octet, which may or may not represent a character. */
typedef unsigned char sHT_octet;
/** A single unsigned octet, which should not be interpreted as a character.
 (E.g. from most image formats). */
typedef sHT_octet sHT_byte;
/** A character (or possibly, part of a UTF-8 sequence), represented by
    an unsigned octet. */
typedef sHT_octet sHT_char;

typedef uint_least16_t sHT_size;
typedef sHT_octet *sHT_paper;

/* Stack */
struct sHT_paper_mill
{
	unsigned int capacity;
	unsigned int length;
	sHT_octet **first;
};

/* May return NULL (allocation failure). */
__attribute__((warn_unused_result))
__attribute__((nonnull (1)))
sHT_paper
sHT_alloc_paper(struct sHT_paper_mill *mill);

/* Assumes mill->length != mill->capacity. Cannot fail. */
__attribute__((nonnull (1, 2)))
void
sHT_free_paper(struct sHT_paper_mill *mill, sHT_paper p);

struct sHT_buffer
{
	sHT_paper first;
	sHT_size offset;
	sHT_size length;
};

#endif
